package com.lovo.ssc.service.impl;

import com.lovo.ssc.bean.Commodity;
import com.lovo.ssc.dao.IWebCommodityDao;
import com.lovo.ssc.dto.BatchDto;
import com.lovo.ssc.dto.WebCommodityDto;
import com.lovo.ssc.mapper.CommodityMapper;
import com.lovo.ssc.service.ICommodityService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * <p>
 * 0-已上架、1-促销中、2-预售商品 服务实现类
 * </p>
 *
 * @author lovo
 * @since 2022-07-11
 */
@Service
@Slf4j
public class CommodityServiceImpl extends ServiceImpl<CommodityMapper, Commodity> implements ICommodityService {
	@Autowired
	RLock lock;
	@Autowired
	RedisTemplate redisTemplate;
	@Autowired
	IWebCommodityDao webCommodityDao;


	@Override
	public void trunCateCommodity() {
		baseMapper.trunCateCommodity();
	}

	@Override
	public Object findCommodity(String state, String type) throws InterruptedException {
		//组装key
		String key = state + type;
//		判断缓存中是否存在该key对应的数据
		if (redisTemplate.hasKey(key)) {
			log.info("key为：" + key);
			//存在
			return redisTemplate.opsForValue().get(key);
		}
		//不存在
		//去数据库查询
		//竞争锁,防止缓存击穿
		Boolean b = lock.tryLock(0, 2, TimeUnit.SECONDS);
		if (b) {//得到锁
			//创建缓存失效时间（用时间戳实现随机）
			Long time = System.currentTimeMillis();
			int time1 = (int) (time % 100);
			if (time1 > 100) {
				time1 = 100;
			} else if (time1 < 5) {
				time1 = 5;
			}

			webCommodityDao.deleteAll();
			//查询数据库
			List<WebCommodityDto> webCommodityDtoList = baseMapper.findCommodity(state, type);
			//将WebCommodityDto的图片放入WebCommodityDto
			int a = 1;
			for (WebCommodityDto w : webCommodityDtoList) {
				w.setImgpathList(baseMapper.findImgPathByCommodityCode(w.getCommoditycode()));
				w.setCommodityId(String.valueOf(a));
				a++;
				//将商品放入es
				log.info("将商品放入es");
				webCommodityDao.save(w);

				log.info(webCommodityDao + "");
			}


			//将数据放入缓存
			redisTemplate.opsForValue().set(key, webCommodityDtoList, 100, TimeUnit.SECONDS);
			//返回缓存数据
			return redisTemplate.opsForValue().get(key);
		} else {
			//休眠3秒
			Thread.sleep(3000);
			//递归
			this.findCommodity(state, type);
		}

		return null;
	}

	@Override
	public Object findCommodity(String code) {
		WebCommodityDto webCommodityDto = baseMapper.findByCommodityCode(code);
		webCommodityDto.setImgpathList(baseMapper.findImgPathByCommodityCode(code));
		return webCommodityDto;
	}

	@Override
	public List<String> findBatchByCode(String code, int number) {
		//得到对应商品编号的批次对象集合
		List<BatchDto> batchDtos = baseMapper.findBatchByCode(code);
		//创建一个集合用来接收批次
		List<String> list = new ArrayList<>();
		for (int i = 0; i < batchDtos.size(); ) {
			//如果该商品批次数量为0，i++以取出下一个批次，，并提前进入下一次循环
			if (batchDtos.get(i).getNumber() == 0) {
				i++;
				continue;
			}
			//得到批次
			list.add(batchDtos.get(i).getBatch());
			batchDtos.get(i).setNumber(batchDtos.get(i).getNumber() - 1);
			//该批次库存-1
			baseMapper.updeteBatchNumberByCode(code, batchDtos.get(i).getBatch());
			//如果取出的数量够了，则返回所需批次集合并结束当前方法
			if (list.size() == number) {
				return list;
			}
		}

		//创建一个假数据数组，保证业务运行
		List<String> list1 = new ArrayList<>();
		list1.add("000");
		list1.add("000");
		list1.add("000");
		list1.add("000");

		return list1;
	}


}
